import { Response } from '../interface';
import { modelToCamelCase } from '../utils/index'


const Sequelize = require('sequelize');
const sassmodel = Symbol('Context#sassmodel');
const shop = Symbol('Context#shop');
const shop_id = Symbol('Context#shop_id');


console.log(sassmodel, shop, shop_id);
let modelSupportFnNames = {

    // 查询的
    'findByPk': { type: 'select' },
    'findOne': { type: 'select' },
    'findOrCreate': { type: 'select' },
    'findAndCountAll': { type: 'select' },
    'findAll': { type: 'select' },
    'findOrBuild': { type: 'select' },
    'count': { type: 'select' },
    'max': { type: 'select' },
    'min': { type: 'select' },
    'sum': { type: 'select' },

    'upsert': { type: 'upsert' },
    'create': { type: 'insert' },
    'bulkCreate': { type: 'insert' },

    'increment': { type: 'update' },
    'decrement': { type: 'update' },

    'update': { type: 'update' },
    'destroy': { type: 'destroy' },

    'new': { type: 'new' }, //不操作数据库

};
module.exports = {
    get isGET() {
        return this.request.method === 'GET';
    },
    get isDELETE() {
        return this.request.method === 'DELETE';
    },
    get isPOST() {
        return this.request.method === 'POST';
    },
    get isPUT() {
        return this.request.method === 'PUT';
    },

    get sassmodel() {

        let ctx = this;
        let _model = {
            transaction: this.app.model.transaction,
            Op: Sequelize.Op,
            Promise: Sequelize.Promise
        };

        this.app.model.modelManager.forEachModel(model => {
            const modelName  = modelToCamelCase(model.name);
            _model[modelName] = {};

            for (let fnName in modelSupportFnNames) {
                _model[modelName][fnName] = function () {
                    //arguments是一个类数组，需要转成array使用，否则无法插入[findAll没有参数时无法附加shop_id]。
                    let args = Array.from(arguments);

                    if (fnName === "new") { //不操作数据库
                        args[0].shop_id = ctx._shop.id;
                        return new model(args[0])
                    }
                    // 这里对 where 进行处理
                    if (fnName === 'findByPk') {
                        if (!args[1]) {
                            args[1] = {};
                        }
                        args[1].where = args[1].where || {};
                        args[1].where.shop_id = ctx._shop.id;
                    } else if (fnName === 'upsert') {
                        if (args[0]) {
                            args[0].shop_id = ctx._shop.id;
                        }
                    } else if (modelSupportFnNames[fnName].type === 'select') {
                        if (!args[0]) {
                            args[0] = {};
                        }
                        args[0].where = args[0].where || {};
                        args[0].where.shop_id = ctx._shop.id;
                    } else if (modelSupportFnNames[fnName].type === 'insert') {

                        if (fnName === 'bulkCreate') {
                            if (args[0] && args[0].length > 0) {
                                args[0].forEach(o => {
                                    o.shop_id = ctx._shop.id;
                                })
                            }
                        } else {
                            if (!args[0]) {
                                args[0] = {};
                            }
                            args[0].shop_id = ctx._shop.id;
                        }

                    } else if (modelSupportFnNames[fnName].type === 'destroy') {
                        if (!args[0]) {
                            args[0] = {};
                        }
                        args[0].where = args[0].where || {};
                        args[0].where.shop_id = ctx._shop.id;
                    } else if (modelSupportFnNames[fnName].type === 'update') {
                        if (!args[1]) {
                            args[1] = {};
                        }
                        args[1].where = args[1].where || {};
                        args[1].where.shop_id = ctx._shop.id;
                    }
                    return model[fnName].apply(model, args);
                }
            }
        });

        // console.log('使用 model 后，执行耗时增加');
        // console.timeEnd("model extend");
        return _model;

    },
    get shop() {
        let ctx = this;

        // 异常退出
        if (!ctx._shop) {
            throw new Error('未找到 ctx._shop');
        }

        return {
            info: async function () {
                let shop_id = ctx._shop.id;
                return await ctx.model.Shop.findOne({ where: { id: shop_id } });
            },
            config: async function () {
                let shop_id = ctx._shop.id;
                let result = await ctx.model.Shop.findOne({ where: { id: shop_id } });
                if (result) {
                    try {
                        return JSON.parse(result.config);
                    } catch (e) {
                        return null
                    }
                } else {
                    return null;
                }
            }
        }
    },

    get shop_id() {
        console.log(this, 'get-show-id');
        return this._shop ? this._shop.id : -1;
    },
    get shop_name() {
        return this._shop ? this._shop.name : '';
    },
    success({
        status = 200,
        code = 0,
        msg = '',
        data = {},
    }: Response = {}): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },

    badRequest({
        status = 400,
        code = 20001,
        msg = '',
        data = {},
    }: Response = {}): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },

    unauthorized({
        status = 200,
        code = 10004,
        msg = '',
        data = {},
    }: Response): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },

    forbidden({
        status = 403,
        code = 20003,
        msg = '',
        data = {},
    }: Response = {}): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },

    notFound({ status = 404, code, msg = '', data = {} }: Response): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },

    failure({
        status = 500,
        code = 20002,
        msg = '',
        data = {},
    }: Response = {}): void {
        this.body = {
            code,
            msg: msg || this.helper.errorMsg(code),
            data,
        };
        this.status = status;
    },
};
